<?php

namespace App\Http\Controllers;

use App\Http\Resources\StorageConfigResource;
use App\Models\StorageConfig;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class StorageConfigController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth.api');
    }

    /**
     * 获取当前存储配置
     * 如果不存在，则创建默认的本地存储配置
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function index()
    {
        $config = StorageConfig::getDefault();
        
        // 如果不存在配置，创建默认的本地存储配置
        if (!$config) {
            $config = StorageConfig::create([
                'type' => StorageConfig::TYPE_LOCAL,
                'name' => '本地存储',
                'is_default' => true,
                'status' => StorageConfig::STATUS_ENABLED,
                'config' => [
                    'root' => 'uploads',
                    'url' => '/storage',
                ],
            ]);
        }

        return $this->success(new StorageConfigResource($config), '获取成功');
    }

    /**
     * 更新存储配置
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function update(Request $request)
    {
        $config = StorageConfig::getDefault();
        
        // 如果不存在配置，创建新的
        if (!$config) {
            $config = new StorageConfig();
            $config->is_default = true;
            $config->status = StorageConfig::STATUS_ENABLED;
        }
        
        $validator = $this->validateStorageConfig($request);

        if ($validator->fails()) {
            return $this->validationError($validator);
        }

        $data = $request->only(['type', 'name', 'config', 'status', 'remark']);
        $data['is_default'] = true; // 始终设置为默认
        
        // 确保只有一个默认配置
        if ($config->id) {
            StorageConfig::where('is_default', true)
                ->where('id', '!=', $config->id)
                ->update(['is_default' => false]);
            $config->update($data);
        } else {
            // 取消所有其他默认配置
            StorageConfig::where('is_default', true)->update(['is_default' => false]);
            $config->fill($data);
            $config->save();
        }

        return $this->success(new StorageConfigResource($config->fresh()), '更新成功');
    }

    /**
     * 测试存储配置连接
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function test(Request $request)
    {
        $validator = $this->validateStorageConfig($request);

        if ($validator->fails()) {
            return $this->validationError($validator);
        }

        // 创建临时配置对象用于测试
        $config = new StorageConfig();
        $config->type = $request->input('type');
        $config->config = $request->input('config');
        
        try {
            $storageService = app(\App\Services\StorageService::class);
            $result = $storageService->testConnection($config);
            
            if ($result) {
                return $this->success(null, '连接测试成功');
            } else {
                return $this->error('连接测试失败', 500);
            }
        } catch (\Exception $e) {
            return $this->error('连接测试失败：' . $e->getMessage(), 500);
        }
    }

    /**
     * 验证存储配置
     *
     * @param Request $request
     * @return \Illuminate\Validation\Validator
     */
    protected function validateStorageConfig(Request $request)
    {
        $rules = [
            'type' => 'required|string|in:' . implode(',', [
                StorageConfig::TYPE_LOCAL,
                StorageConfig::TYPE_ALIYUN_OSS,
                StorageConfig::TYPE_TENCENT_COS,
                StorageConfig::TYPE_QINIU,
            ]),
            'name' => 'required|string|max:100',
            'is_default' => 'nullable|boolean',
            'status' => 'required|integer|in:' . implode(',', [
                StorageConfig::STATUS_DISABLED,
                StorageConfig::STATUS_ENABLED,
            ]),
            'remark' => 'nullable|string',
        ];

        // 根据类型验证配置
        $type = $request->input('type');
        $configRules = $this->getConfigRulesByType($type);
        
        $rules['config'] = ['required', 'array'];
        foreach ($configRules as $key => $rule) {
            $rules["config.{$key}"] = $rule;
        }

        return Validator::make($request->all(), $rules, [
            'type.required' => '存储类型不能为空',
            'type.in' => '不支持的存储类型',
            'name.required' => '配置名称不能为空',
            'config.required' => '存储配置不能为空',
            'config.array' => '存储配置必须是数组',
        ]);
    }

    /**
     * 根据类型获取配置验证规则
     *
     * @param string $type
     * @return array
     */
    protected function getConfigRulesByType(string $type): array
    {
        $rules = [];

        switch ($type) {
            case StorageConfig::TYPE_LOCAL:
                $rules = [
                    'root' => 'nullable|string',
                    'url' => 'nullable|string',
                ];
                break;

            case StorageConfig::TYPE_ALIYUN_OSS:
                $rules = [
                    'access_key_id' => 'required|string',
                    'access_key_secret' => 'required|string',
                    'bucket' => 'required|string',
                    'endpoint' => 'required|string',
                    'domain' => 'nullable|string',
                    'is_cname' => 'nullable|boolean',
                ];
                break;

            case StorageConfig::TYPE_TENCENT_COS:
                $rules = [
                    'secret_id' => 'required|string',
                    'secret_key' => 'required|string',
                    'region' => 'required|string',
                    'bucket' => 'required|string',
                    'domain' => 'nullable|string',
                ];
                break;

            case StorageConfig::TYPE_QINIU:
                $rules = [
                    'access_key' => 'required|string',
                    'secret_key' => 'required|string',
                    'bucket' => 'required|string',
                    'domain' => 'nullable|string',
                ];
                break;
        }

        return $rules;
    }
}

